package com.mic.yzzn.plc.common.instructions.request;

import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;

import com.mic.yzzn.plc.common.ins.datastructure.PLCDataRegisterNumber;
import com.mic.yzzn.plc.common.instructions.basic.PLCRequestInstruction;

/**
 * Created by ASH on 16/3/8.
 */
public class PLCDataRegisterWriteInstruction extends PLCDataRegisterInstruction
{
	/** 写入数据 */
    ArrayList<String> writeData;

    /**
     * 初始化方法
     */
    public PLCDataRegisterWriteInstruction()
    {
        new PLCDataRegisterInstruction();

        requestCode = PLCRequestInstruction.WRITE_DATA_AREA_INS;
        writeData = new ArrayList<String>();
    }

    /**
     * 写入数据get方法
     * @return 写入数据
     */
    public ArrayList<String> getWriteData()
    {
        return writeData;
    }

    public void setWriteData(ArrayList<String> writeData) throws IllegalArgumentException
    {
        if (writeData.size() != dataRegisterNumber.range())
        {
            throw new IllegalArgumentException("writeData must have same size as dataRegisterNumber's range");
        }

        this.writeData = writeData;
    }

    /**
     * 转换成字符串
     */
    @Override
    public String toString()
    {
        // 拼接指令字符串
        StringBuffer buffer = new StringBuffer();
        buffer.append(instructionHeader);
        buffer.append(locationNumber_high);
        buffer.append(locationNumber_low);
        buffer.append(instructionTypeCode);
        buffer.append(requestCode);
        buffer.append(dataCode);
        buffer.append(dataRegisterNumber.toString());

        for (int i = 0; i < writeData.size(); ++i)
        {
            buffer.append(writeData.get(i));
        }

        buffer.append(getBBC_high());
        buffer.append(getBBC_low());
        buffer.append(instructionEnd);

        return buffer.toString();
    }

    /**
     * 计算每一位的异或并返回
     */
    @Override
    protected int getXORByBit()
    {
        int i, j = 0;
        int result = 0;
        String data = "";

        for (i = 0; i < writeData.size(); ++i)
        {
            data = writeData.get(i);
            for (j = 0; j < data.length(); ++j)
            {
                result ^= data.charAt(j);
            }
        }

        return super.getXORByBit() ^ result;
    }
    
    /**
     * 用字符串初始化
     */
    @Override
    public String initWithString(String instructionString) throws IllegalArgumentException
    {
    	String tempResult = super.initWithString(instructionString);
    	
    	// 判断请求码与当前指令的请求码是否符合
    	int requestCodeLength = requestCode.length();
    	if (!(StringUtils.substring(tempResult, 0, requestCodeLength).equals(requestCode)))
		{
			throw new IllegalArgumentException("PLCSingleContactorReadInstruction's requestCode must be \"" + requestCode +"\"");
		}
    	
    	// 截取请求码
    	tempResult = StringUtils.substringAfter(tempResult, requestCode);
//    	System.out.println(tempResult);

    	// 获取数据代码
    	String dataCode = tempResult.substring(0, 1);
    	this.dataCode = dataCode;
    	
    	// 截断数据代码
    	tempResult = StringUtils.substringAfter(tempResult, dataCode);
//    	System.out.println(tempResult);

    	// 判断数据范围是否正确
    	if (tempResult.length() < 10)
		{
			throw new IllegalArgumentException("the length PLCDataRegisterNumber's beginNumber and endNumber must be 5");
		}
    	
    	// 设置数据范围
    	this.dataRegisterNumber = new PLCDataRegisterNumber(tempResult.substring(0, 5), tempResult.substring(5, 10));
    	
    	// 截断数据范围
    	tempResult = StringUtils.substringAfter(tempResult, dataRegisterNumber.toString());
//    	System.out.println(tempResult);

    	// 判断数据是否符合范围
    	if (tempResult.length() / 4 != dataRegisterNumber.range())
		{
			throw new IllegalArgumentException("the number PLCDataRegisterNumber's writeData must equal to range");
		}
    	
    	// 添加数据
    	for (int i= 0; i < tempResult.length(); i += 4)
    	{
    		writeData.add(tempResult.substring(i, i + 4));
    	}
    	
    	// 截断数据
    	tempResult = tempResult.substring(0, tempResult.length());
    	
    	return tempResult;
    }
}
